import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actions as noticeActions } from '@redux/reducer/notice';
import { Select, Button, message, Pagination, Spin, Empty } from 'antd';
import moment from 'moment';
import _ from 'lodash';

import { getNotifyList, modifyNotifyStatus, deleteReadNotify } from '@api/notify';
import AssetDetectImage from './images/asset-detect.svg';
import NotifyOneDayImage from './images/notify-1day.svg';
import VersionUpdateImage from './images/version-update.svg';
import WeakPasswordImage from './images/weak-password.svg';
import OnedayUpdateImage from './images/oneday-update.svg';
import SiteChangeImage from './images/site-change-notice.svg';
import AssetDetectDisabledImage from './images/asset-detect-disabled.svg';
import NotifyOneDayDisabledImage from './images/notify-1day-disabled.svg';
import VersionUpdateDisabledImage from './images/version-update-disabled.svg';
import WeakPasswordDisabledImage from './images/weak-password-disabled.svg';
import OnedayUpdateDisabledImage from './images/oneday-update-disabled.svg';
import SiteChangeDisabledImage from './images/site-change-notice-disabled.svg';
import VulDetectImage from './images/vul-detect.svg';
import VulDetectDisabledImage from './images/vul-detect-disabled.svg';
import './index.less';

const iconType = {
  Zoomeye: AssetDetectImage,
  OneDay: NotifyOneDayImage,
  version: VersionUpdateImage,
  WeakPassword: WeakPasswordImage,
  OnedayUpdate: OnedayUpdateImage,
  siteModify: SiteChangeImage,
  VulDetect: VulDetectImage
};

const iconTypeDisabled = {
  Zoomeye: AssetDetectDisabledImage,
  OneDay: NotifyOneDayDisabledImage,
  version: VersionUpdateDisabledImage,
  WeakPassword: WeakPasswordDisabledImage,
  OnedayUpdate: OnedayUpdateDisabledImage,
  siteModify: SiteChangeDisabledImage,
  VulDetect: VulDetectDisabledImage
};

const iconWidth = {
  Zoomeye: 24,
  OneDay: 24,
  version: 24,
  OnedayUpdate: 24,
  WeakPassword: 24,
  siteModify: 21,
  VulDetect: 24
};

const iconMargin = {
  Zoomeye: 0,
  OneDay: 0,
  version: 0,
  WeakPassword: '-4px',
  VulDetect: 0
};

const notifyTitleMap = {
  OneDay: '1DAY检测',
  OnedayUpdate: '漏洞情报',
  version: '版本更新',
  Zoomeye: '资产探测',
  WeakPassword: '弱口令',
  siteModify: '资产更新',
  VulDetect: '漏洞普查'
};
const prefixCls = 'Notify';
const { Option } = Select;

class Notify extends Component {
  constructor(props) {
    super(props);
    this.state = {
      notifys: [],
      count: 0,
      loading: false,
      filter: {
        page: 1,
        pageSize: 10,
        type: ''
      },
      hasOneDayModule: false
    };
  }
  componentDidMount() {
    const { modules = [] } = this.props;
    const hasOneDayModule = modules.includes('1day');
    this.setState({
      hasOneDayModule
    });
    this.getNotifyList();
  }
  //获取列表
  getNotifyList = () => {
    this.setState({ loading: true });
    const { filter } = this.state;
    getNotifyList(filter)
      .then(res => {
        this.setState({
          //根据之后接口重写
          notifys: res.data.data.list,
          count: res.data.data.count,
          loading: false
        });
      })
      .catch(() => {
        message.error('获取列表失败');
        this.setState({ loading: false });
      });
  };
  modifyNotifyStatus = ids => {
    const noticeIds = Array.isArray(ids) ? ids : [ids];
    this.setState({ loading: true });
    // eslint-disable-next-line
    modifyNotifyStatus({ notice_ids: noticeIds })
      .then(() => {
        this.getNotifyList();
        this.props.loadNotice();
      })
      .catch(error => {
        message.error(error);
        this.setState({ loading: false });
      });
  };
  // 标记为已读
  setRead = (id, e) => {
    e && e.stopPropagation();
    this.modifyNotifyStatus(id);
  };
  // 删除已读
  onClickDeleteRead = () => {
    deleteReadNotify()
      .then(() => {
        this.getNotifyList();
      })
      .catch(error => {
        message.error(error);
        this.setState({ loading: false });
      });
  };
  onClickAllRead = () => {
    modifyNotifyStatus()
      .then(() => {
        this.getNotifyList();
        this.props.loadNotice();
      })
      .catch(error => {
        message.error(error);
      });
  };

  //筛选变化
  onLevelChange = value => {
    let { filter } = this.state;
    filter.type = value;
    filter.page = 1;
    this.setState({ filter }, this.getNotifyList);
  };
  onStatusChange = value => {
    let { filter } = this.state;
    filter.read = value;
    filter.page = 1;
    this.setState({ filter }, this.getNotifyList);
  };
  onTypeChange = value => {
    let { filter } = this.state;
    filter.origin = value;
    filter.page = 1;
    this.setState({ filter }, this.getNotifyList);
  };
  //页码及大小变化
  onPageChange = page => {
    document.getElementsByClassName('ant-layout-content')[0].scrollTop = 0;
    let { filter } = this.state;
    filter.page = page;
    this.setState({ filter }, this.getNotifyList);
  };
  onShowSizeChange = (current, size) => {
    let { filter } = this.state;
    filter.page = current;
    filter.pageSize = size;
    this.setState({ filter }, this.getNotifyList);
  };
  renderNotifyList = () => {
    const { notifys, loading } = this.state;
    return (
      <Spin tip="加载中" spinning={loading}>
        <div>
          {notifys.map(item => {
            const { origin, task_oid: taskId, created, type, _id } = item;
            const isDeleted = taskId && taskId.isDeleted;
            const status = item.read ? 'read' : 'unread';
            let taskOid;
            taskId && taskId._id ? (taskOid = taskId._id) : null;
            let url;
            if (origin === 'Zoomeye' && taskOid) {
              url = `/task-manage/zoomeye-detail/${taskOid}`;
            } else if ((origin === 'OneDay' || origin === 'WeakPassword') && taskOid) {
              url = `/task-manage/oneday-detail/${taskOid}`;
            } else if (origin === 'OnedayUpdate') {
              url = '/vul/oneday-detection';
            } else if (origin === 'siteModify') {
              url = 'asset-manage';
            } else if (origin === 'VulDetect') {
              url = `/task-manage/vul-detect-detail/${taskOid}`; // TODO 改成漏洞普查任务详情页
            }
            const cls = classNames(`${prefixCls}-list-item`, status);
            const image = status === 'read' ? iconTypeDisabled[origin] : iconType[origin];
            return (
              notifyTitleMap[origin] && (
                <div className={cls} key={item._id}>
                  <div
                    className={`${prefixCls}-list-item-message`}
                    onClick={e => this.setRead(_id, e)}
                  >
                    <Link
                      to={url}
                      onClick={e => {
                        if (isDeleted) {
                          e.preventDefault();
                        }
                      }}
                    >
                      <div>
                        <img
                          src={image}
                          width={iconWidth[origin]}
                          style={{ margin: iconMargin[origin] }}
                          alt=""
                        />
                        <span className={`${prefixCls}-list-item-message-title`}>
                          {notifyTitleMap[origin]}
                        </span>
                        <span>{moment(created).format('YYYY-MM-DD HH:mm')}</span>
                        {type === 'warning' && (
                          <span className={`${prefixCls}-warn-tag`}>告警</span>
                        )}
                      </div>
                      <div style={{ margin: '12px 0 0 38px' }}>
                        <span>{item.message}</span>
                      </div>
                    </Link>
                  </div>
                  <div className={`${prefixCls}-list-item-handle`}>
                    {!item.read ? (
                      <span
                        onClick={e => this.setRead(_id, e)}
                        style={{ cursor: 'pointer' }}
                        className="be-color"
                      >
                        标为已读
                      </span>
                    ) : (
                      <span>已读</span>
                    )}
                  </div>
                </div>
              )
            );
          })}
        </div>
      </Spin>
    );
  };
  renderTypeSelect = (hasOneDayModule, role) => {
    let BaseSelect = [{ name: '全部', value: '' }];
    let OneDayModuleSelect = [
      { name: '1DAY检测', value: 'OneDay' },
      { name: '弱口令', value: 'WeakPassword' },
      { name: '漏洞普查', value: 'VulDetect' }
    ];
    if (role) {
      BaseSelect.push(
        ...{
          安全管理员: hasOneDayModule
            ? [
                ...OneDayModuleSelect,
                { name: '资产探测', value: 'Zoomeye' },
                { name: '资产变更', value: 'siteModify' }
              ]
            : [{ name: '资产探测', value: 'Zoomeye' }, { name: '资产变更', value: 'siteModify' }],
          系统管理员: [{ name: '版本更新', value: 'version' }],
          审计员: []
        }[role]
      );
    }

    return BaseSelect.map(r => {
      return (
        <Option value={r.value} key={r.value}>
          {r.name}
        </Option>
      );
    });
  };
  render() {
    const { notifys, count, hasOneDayModule } = this.state;
    const { role } = this.props;
    return (
      <div className={prefixCls}>
        <div className={`${prefixCls}-page-title`}>通知</div>
        <div style={{ display: 'flex', justifyContent: 'space-between', margin: '28px 0' }}>
          <div className={`${prefixCls}-filter`}>
            <div className={`${prefixCls}-filter-item`}>
              <span style={{ marginRight: 16 }}>消息分类</span>
              <Select
                style={{ width: 120 }}
                defaultValue=""
                onChange={this.onTypeChange}
                getPopupContainer={triggerNode => triggerNode.parentNode}
              >
                {this.renderTypeSelect(hasOneDayModule, role)}
              </Select>
            </div>
            <div className={`${prefixCls}-filter-item`}>
              <span style={{ marginRight: 16 }}>消息等级</span>
              <Select
                style={{ width: 120 }}
                defaultValue=""
                onChange={this.onLevelChange}
                getPopupContainer={triggerNode => triggerNode.parentNode}
              >
                <Option value="">全部</Option>
                <Option value="warning">告警</Option>
                <Option value="event">普通</Option>
              </Select>
            </div>
            <div className={`${prefixCls}-filter-item`}>
              <span style={{ marginRight: 16 }}>阅读情况</span>
              <Select
                style={{ width: 120 }}
                defaultValue=""
                onChange={this.onStatusChange}
                getPopupContainer={triggerNode => triggerNode.parentNode}
              >
                <Option value="">全部</Option>
                <Option value="false">未读</Option>
                <Option value="true">已读</Option>
              </Select>
            </div>
          </div>
          <div>
            <Button type="danger" style={{ marginRight: 16 }} onClick={this.onClickDeleteRead}>
              删除已读通知
            </Button>
            <Button onClick={this.onClickAllRead}>全部标记为已读</Button>
          </div>
        </div>
        <div>
          <span style={{ color: '#999ea8' }}>当前共“{count}”条消息</span>
        </div>
        <div style={{ borderTop: '1px solid #f2f2f2', marginTop: 24 }}>
          {notifys.length ? (
            this.renderNotifyList()
          ) : (
            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
          )}
        </div>
        <div style={{ position: 'relative', height: 32, marginTop: 16 }}>
          <Pagination
            total={count}
            current={this.state.filter.page}
            showTotal={count => `共 ${count} 条`}
            showSizeChanger
            style={{ position: 'absolute', right: 0 }}
            onChange={this.onPageChange}
            showQuickJumper={true}
            onShowSizeChange={this.onShowSizeChange}
          />
        </div>
      </div>
    );
  }
}

Notify.propTypes = {
  history: PropTypes.object,
  loadNotice: PropTypes.func,
  modules: PropTypes.array,
  role: PropTypes.string
};

const mapStateToProps = state => {
  return {
    modules: _.get(state, 'auth.cert.modules', []),
    role: _.get(state, 'auth.user.role', '')
  };
};

const mapDispatchToProps = dispatch => {
  return {
    ...bindActionCreators(noticeActions, dispatch)
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Notify);
